<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Report</title>	
    <style>
		
		html, body {
			scroll-behavior: smooth;
		}
		.back_top {
			position: fixed;
			bottom: 20px;
			right: 20px;
			height: 50px;
			width: 50px;
			display: none;
			background: #0000003d;
			border-radius: 10px;
		}
		.back_top:before {
			content: "";
			position: absolute;
			inset: 30%;
			transform: translateY(20%) rotate(-45deg);
			border-top: 5px solid #fff;
			border-right: 5px solid #fff;
		}
		h1 {
			font-size: 18px;
			color: black;
		}
		h2 {
			font-size: 18px;
			color: black;
		}
		p {
			font-size: 14px;
		}
		span.passed,
		.passed .col-result {
			color: green;
		}
		span.failed,
		.failed .col-result {
			color: red;
		}
		#results-table {
			color: #999;
			font-size: 12px;
			width: 100%;
		}
		#results-table th,
		#results-table td {
			padding: 5px;
			border: 1px solid #E6E6E6;
			text-align: left;
			border-collapse: collapse;
		}
		#results-table th {
			font-weight: bold;
		}
    </style>
</head>
	<body onLoad="init()">
		<script>
		
			window.onload = function() {
				var backToTopBtn = document.getElementById('back-to-top');
				window.onscroll = function() {
					if (document.documentElement.scrollTop >= 100) {
							backToTopBtn.style.display = 'block';
					} else {
							backToTopBtn.style.display = 'none';
					}
				}
				backToTopBtn.onclick = function() {
					document.documentElement.scrollTop = 0;
				}
			}

			function toArray(iter) {
				if (iter === null) {
					return null;
				}
				return Array.prototype.slice.call(iter);
			}

			function find(selector, elem) { // eslint-disable-line no-redeclare
				if (!elem) {
					elem = document;
				}
				return elem.querySelector(selector);
			}

			function findAll(selector, elem) {
				if (!elem) {
					elem = document;
				}
				return toArray(elem.querySelectorAll(selector));
			}

			function sortColumn(elem) {
				toggleSortStates(elem);
				const colIndex = toArray(elem.parentNode.childNodes).indexOf(elem);
				let key;
				if (elem.classList.contains('result')) {
					key = keyResult;
				} else if (elem.classList.contains('links')) {
					key = keyLink;
				} else {
					key = keyAlpha;
				}
				sortTable(elem, key(colIndex));
			}

			function showFilters() {
				let visibleString = getQueryParameter('visible') || 'all';
				visibleString = visibleString.toLowerCase();
				const checkedItems = visibleString.split(',');

				const filterItems = document.getElementsByClassName('filter');
				for (let i = 0; i < filterItems.length; i++) {
					filterItems[i].hidden = false;

					if (visibleString != 'all') {
						filterItems[i].checked = checkedItems.includes(filterItems[i].getAttribute('data-test-result'));
						filterTable(filterItems[i]);
					}
				}
			}

			function getQueryParameter(name) {
				const match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
				return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
			}

			function init () { // eslint-disable-line no-unused-vars

				showFilters();

				sortColumn(find('.initial-sort'));

				findAll('.sortable').forEach(function(elem) {
					elem.addEventListener('click',
						function() {
							sortColumn(elem);
						}, false);
				});
			}

			function sortTable(clicked, keyFunc) {
				const rows = findAll('.results-table-row');
				const reversed = !clicked.classList.contains('asc');
				const sortedRows = sort(rows, keyFunc, reversed);
				/* Whole table is removed here because browsers acts much slower
				 * when appending existing elements.
				 */
				const thead = document.getElementById('results-table-head');
				document.getElementById('results-table').remove();
				const parent = document.createElement('table');
				parent.id = 'results-table';
				parent.appendChild(thead);
				sortedRows.forEach(function(elem) {
					parent.appendChild(elem);
				});
				document.getElementsByTagName('BODY')[0].appendChild(parent);
			}

			function sort(items, keyFunc, reversed) {
				const sortArray = items.map(function(item, i) {
					return [keyFunc(item), i];
				});

				sortArray.sort(function(a, b) {
					const keyA = a[0];
					const keyB = b[0];

					if (keyA == keyB) return 0;

					if (reversed) {
						return keyA < keyB ? 1 : -1;
					} else {
						return keyA > keyB ? 1 : -1;
					}
				});

				return sortArray.map(function(item) {
					const index = item[1];
					return items[index];
				});
			}

			function filterTable(elem) { // eslint-disable-line no-unused-vars
				const outcomeAtt = 'data-test-result';
				const outcome = elem.getAttribute(outcomeAtt);
				const classOutcome = outcome + ' results-table-row';
				const outcomeRows = document.getElementsByClassName(classOutcome);

				for(let i = 0; i < outcomeRows.length; i++){
					outcomeRows[i].hidden = !elem.checked;
				}

				const rows = findAll('.results-table-row').filter(isAllRowsHidden);
				const allRowsHidden = rows.length == 0 ? true : false;
				const notFoundMessage = document.getElementById('not-found-message');
				notFoundMessage.hidden = !allRowsHidden;
			}
		</script>
		<h1 align="left">后端接口扫描报告</h1>
		<br>
		<h2>结果汇总</h2>
		<hr>
		<p>
			总数量：<span style="font-weight:bold; color:blue">{{total_num}}</span>，
			成功数量：<span class="passed" style="font-weight:bold">{{success_num}}</span>，
			失败数量：<span class="failed" style="font-weight:bold">{{fail_num}}</span>
		</p>
		<p>开始时间：{{start_time}}</p>
		<p>结束时间：{{end_time}}</p>
		<p>耗时：{{interval}}s</p>
		<p>是否登录：{{is_auth}}</p>
		<h2>详细信息</h2>
		<hr>
		<p class="filter" >勾选/取消 查看测试结果</p>
		<input checked="true" class="filter" data-test-result="passed" name="filter_checkbox" onChange="filterTable(this)" type="checkbox"/>通过(<span class="passed" style="font-weight:bold">{{success_num}}</span>)&nbsp;
		<input checked="true" class="filter" data-test-result="failed" name="filter_checkbox" onChange="filterTable(this)" type="checkbox"/>失败(<span class="failed" style="font-weight:bold">{{fail_num}}</span>)
		<table id="results-table">
			<thead id="results-table-head">
				<tr>
					<th class="sortable" col="result">结果</th>
					<th class="sortable" col="code">响应码</th>
					<th class="sortable" col="url">地址</th>
					<th class="sortable" col="body">响应内容</th>
				</tr>
			</thead>
			{% for fail_item in fail_list %}
			<tbody class="failed results-table-row">
				<tr>
					<td class="col-result">{{fail_item.result}}</td>
					<td class="col-code">{{fail_item.code}}</td>
					<td class="col-url"><a href='{{fail_item.url}}'>{{fail_item.url}}</a></td>
					<td class="col-body">{{fail_item.body}}</td>
				</tr>
			</tbody>
			{% endfor %}
			{% for pass_item in pass_list %}
			<tbody class="passed results-table-row">
				<tr>
					<td class="col-result">{{pass_item.result}}</td>
					<td class="col-code">{{pass_item.code}}</td>
					<td class="col-url"><a href='{{pass_item.url}}'>{{pass_item.url}}</a></td>
					<td class="col-body">{{pass_item.body}}</td>
				</tr>
			</tbody>
			{% endfor %}
			<button id="back-to-top" class="back_top"></button>
		</table>
	</body>
</html>